home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Speccy ClassiX 1998
/
Speccy ClassiX 98.iso
/
amiga_system
/
the_aminet
/
dev
/
debug
/
flush.lha
/
Flush
/
Flush.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-11-01
|
9KB
|
350 lines
/*
* Flush
* Selectively remove unused libraries, devices and fonts from memory.
*
* Written by Septh (Stephan Schreiber)
*/
#include <string.h>
#include <exec/types.h>
#include <exec/nodes.h>
#include <exec/lists.h>
#include <exec/memory.h>
#include <exec/libraries.h>
#include <exec/devices.h>
#include <exec/execbase.h>
#include <dos/dos.h>
#include <dos/dosasl.h>
#include <graphics/text.h>
#include <graphics/gfxbase.h>
#include <clib/exec_protos.h>
#include <clib/dos_protos.h>
#include <clib/graphics_protos.h>
#include <pragmas/exec_sysbase_pragmas.h>
#include <pragmas/dos_pragmas.h>
#include <pragmas/graphics_pragmas.h>
/******************************************************************************
* Constants and macros
******************************************************************************/
#define TEMPLATE "NAMES/M,LIBS=LIBRARIES/S,DEVS=DEVICES/S,FONTS/S,ALL/S,QUIET/S"
enum
{ OPT_NAMES = 0, // Name(s) of libs/devs/fonts to flush
OPT_LIBS, // Limit flush to libraries
OPT_DEVS, // Limit flush to devices
OPT_FONTS, // Limit flush to fonts
OPT_ALL, // Flush libs, devs AND fonts
OPT_QUIET, // Shut up!
NUM_OPTS
};
/* Short-cuts */
#define lib_Succ lib_Node.ln_Succ
#define lib_Name lib_Node.ln_Name
#define dd_Succ dd_Library.lib_Node.ln_Succ
#define dd_Name dd_Library.lib_Node.ln_Name
#define tf_Succ tf_Message.mn_Node.ln_Succ
#define tf_Name tf_Message.mn_Node.ln_Name
/******************************************************************************
* Globals
******************************************************************************/
UBYTE *version = "\0$VER: Flush 1.0 (30.10.95)";
struct Library *SysBase;
struct Library *DOSBase;
struct Library *GfxBase;
UBYTE *def_names[] =
{ "#?",
NULL
};
/******************************************************************************
* Prototypes
******************************************************************************/
VOID flush_fonts(UBYTE **names, LONG quiet);
VOID flush_devs(UBYTE **names, LONG quiet);
VOID flush_libs(UBYTE **names, LONG quiet);
/******************************************************************************
* Program entry point
******************************************************************************/
LONG __saveds main(UBYTE *cmdline)
{
struct Process *me;
struct Message *wbmsg;
struct RDArgs *rda;
ULONG opts[NUM_OPTS];
/* Get SysBase */
SysBase = *((struct Library **)4L);
/* Minimal WB startup */
me = (struct Process *)FindTask(NULL);
if (me->pr_CLI == NULL)
{ WaitPort(&me->pr_MsgPort);
wbmsg = GetMsg(&me->pr_MsgPort);
}
else wbmsg = NULL;
/* Open the libraries */
if (DOSBase= OpenLibrary("dos.library", 37L))
{ if (GfxBase = OpenLibrary("graphics.library", 0L))
{ /* When run under Workbench,
* no arguments are usable.
*/
if (wbmsg)
{ flush_fonts(def_names, TRUE);
flush_devs(def_names, TRUE);
flush_libs(def_names, TRUE);
}
else
{ /* Get shell arguments */
memset(opts, '\0', sizeof(opts));
rda = ReadArgs(TEMPLATE, opts, NULL);
/* Break ? */
if (CheckSignal(SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C)
{ if (rda)
{ FreeArgs(rda);
rda = NULL;
}
SetIoErr(ERROR_BREAK);
}
if (rda)
{ /* ALL ? */
if (opts[OPT_ALL] || (!opts[OPT_LIBS] && !opts[OPT_DEVS] && !opts[OPT_FONTS]))
{ opts[OPT_LIBS] = DOSTRUE;
opts[OPT_DEVS] = DOSTRUE;
opts[OPT_FONTS] = DOSTRUE;
}
/* Here we begin with fonts for aesthetics reasons:
* if we flushed the libraries before the fonts,
* then we could not report which fonts would get flushed.
* This is because when flushed, diskfont.library
* simply removes all unsued fonts still in memory.
*/
/* FONTS ? */
if (opts[OPT_FONTS])
flush_fonts((UBYTE **)opts[OPT_NAMES], opts[OPT_QUIET]);
/* These two could use a single function... */
/* DEVS ? */
if (opts[OPT_DEVS])
flush_devs((UBYTE **)opts[OPT_NAMES], opts[OPT_QUIET]);
/* LIBS ? */
if (opts[OPT_LIBS])
flush_libs((UBYTE **)opts[OPT_NAMES], opts[OPT_QUIET]);
FreeArgs(rda);
}
else PrintFault(IoErr(), NULL);
}
CloseLibrary(GfxBase);
}
CloseLibrary(DOSBase);
}
/* Back to WB ? */
if (wbmsg)
{ Forbid();
ReplyMsg(wbmsg);
}
return(RETURN_OK);
}
/******************************************************************************
* Flush unused fonts
******************************************************************************/
VOID flush_fonts(UBYTE **names, LONG quiet)
{
struct List *fonts_list;
struct TextFont *font;
UBYTE pat[256], font_name[256];
UWORD font_size;
struct TextFont *tmp_font;
/* Get the fonts list */
fonts_list = &(((struct GfxBase *)GfxBase)->TextFonts);
if (names == NULL)
names = def_names;
while (*names)
{ /* Allow for wildcards in names */
ParsePatternNoCase(*names++, pat, sizeof(pat));
Forbid();
/* Font each font in the system... */
for (font = (struct TextFont *)fonts_list->lh_Head; font->tf_Succ; font = (struct TextFont *)font->tf_Succ)
{ /* Check number of accessors of this font
* See if name matches
*/
if ((font->tf_Accessors == 0) && MatchPatternNoCase(pat, font->tf_Name))
{ /* Copy name in temp buffer */
strcpy(font_name, font->tf_Name);
/* Copy font size, too */
font_size = font->tf_YSize;
/* Ok, let's flush it */
StripFont(font); // Fonts won't flush without this!
RemFont(font);
/* Check if it really flushed */
tmp_font = (struct TextFont *)fonts_list;
while (tmp_font = (struct TextFont *)FindName((struct List *)tmp_font, font_name))
{ if (tmp_font == font)
break;
}
if (tmp_font == NULL)
{ /* Tell them it's done */
if (!quiet)
{ Permit();
Printf("font \"%s\", size %ld flushed\n", font_name, font_size);
Forbid();
}
/* Go back to start of list.
* Note that because we are in a for() loop,
* the 'font = font->tf_Succ' statement
* will be executed *after* this one.
* So we have to make 'font' point to
* the list header rather than to the head node,
* or we'll miss the first font in the list.
*/
font = (struct TextFont *)fonts_list;
}
}
}
}
}
/******************************************************************************
* Flush unused devices
******************************************************************************/
VOID flush_devs(UBYTE **names, LONG quiet)
{
struct List *devs_list;
struct Device *dev;
UBYTE pat[256], dev_name[256];
/* Get the devices list */
devs_list = &(((struct ExecBase *)SysBase)->DeviceList);
if (names == NULL)
names = def_names;
while (*names)
{ /* Allows for wildcards in names */
ParsePatternNoCase(*names++, pat, sizeof(pat));
Forbid();
/* for each device in the list... */
for (dev = (struct Device *)devs_list->lh_Head; dev->dd_Succ; dev = (struct Device *)dev->dd_Succ)
{ /* Check opencount of this device.
* See if name matches.
*/
if ((dev->dd_Library.lib_OpenCnt == 0) && MatchPatternNoCase(pat, dev->dd_Name))
{ /* Copy name in temp buffer */
strcpy(dev_name, dev->dd_Name);
/* Ok, let's flush it */
RemDevice(dev);
/* Check if it really flushed */
if (FindName(devs_list, dev_name) == NULL)
{ /* Tell them it's done */
if (!quiet)
{ Permit();
Printf("Device \"%s\" flushed\n", dev_name);
Forbid();
}
/* Go back to start of list.
* Note that because we are in a for() loop,
* the 'dev = dev->dd_Succ' statement
* will be executed *after* this one.
* So we have to make 'dev' point to
* the list header rather than to the head node,
* or we'll miss the first device in the list.
*/
dev = (struct Device *)devs_list;
}
}
}
Permit();
}
}
/******************************************************************************
* Flush unused libraries
******************************************************************************/
VOID flush_libs(UBYTE **names, LONG quiet)
{
struct List *libs_list;
struct Library *lib;
UBYTE pat[256], lib_name[256];
/* Get the libraries list */
libs_list = &(((struct ExecBase *)SysBase)->LibList);
if (names == NULL)
names = def_names;
while (*names)
{ /* Allows for wildcards in names */
ParsePatternNoCase(*names++, pat, sizeof(pat));
Forbid();
/* for each library in the system... */
for (lib = (struct Library *)libs_list->lh_Head; lib->lib_Succ; lib = (struct Library *)lib->lib_Succ)
{ /* Check opencount of this library.
* See if name matches.
*/
if ((lib->lib_OpenCnt == 0) && MatchPatternNoCase(pat, lib->lib_Name))
{ /* Copy name in temp buffer */
strcpy(lib_name, lib->lib_Name);
/* Ok, let's flush it */
RemLibrary(lib);
/* Check if it really flushed */
if (FindName(libs_list, lib_name) == NULL)
{ /* Tell them it's done */
if (!quiet)
{ Permit();
Printf("Library \"%s\" flushed\n", lib_name);
Forbid();
}
/* Go back to start of list.
* Note that because we are in a for() loop,
* the 'lib = lib->lib_Succ' statement
* will be executed *after* this one.
* So we have to make 'lib' point to
* the list header rather than to the head node,
* or we'll miss the first library in the list.
*/
lib = (struct Library *)libs_list;
}
}
}
Permit();
}
}